package com.yoki.cloud.common.protocol.radius.msg.parser;

import com.yoki.cloud.common.protocol.radius.exception.RadiusCodeErrorException;
import com.yoki.cloud.common.protocol.radius.exception.RadiusException;
import com.yoki.cloud.common.protocol.radius.msg.packet.RadiusMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.ReqRadiusMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.RespRadiusMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.acct.req.AccountingRequestMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.acct.resp.AccountingResponseMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.check.req.AccessRequestMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.check.resp.AccessAcceptMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.check.resp.AccessChallengeMsg;
import com.yoki.cloud.common.protocol.radius.msg.packet.check.resp.AccessRejectMsg;

/**
 * @author Sky$
 * @Description: TODO
 * @date 2018/1/15$ 13:41$
 */
public class RadiusPacketParser {

    /**
     * 用于将Radius数据包解析成RadiusMsg类
     *
     * @param input
     * @return
     */
    public static ReqRadiusMsg parseReqPacket(byte[] input, String secret) {
        if (null == input) {
            throw new NullPointerException();
        }
        ReqRadiusMsg msg = null;
        int code = input[RadiusMsg.INDEX_CODE];
        try {
            switch (code) {
                case AccessRequestMsg.PACKET_CODE:
                    msg = new AccessRequestMsg(secret);
                    break;

                case AccountingRequestMsg.PACKET_CODE:
                    msg = new AccountingRequestMsg(secret);
                    break;
                default:
                    throw new RadiusCodeErrorException();
            }
            msg.parse(input);
        } catch (RadiusException e) {
            e.printStackTrace();
        }
        return msg;
    }

    /**
     * 用于将Radius数据包解析成RadiusMsg类
     *
     * @param input
     * @return
     */
    public static RespRadiusMsg parseRespPacket(byte[] input, String secret, RadiusMsg reqMsg) {
        if (null == input) {
            throw new NullPointerException();
        }
        RespRadiusMsg msg = null;
        int code = input[RadiusMsg.INDEX_CODE];
        try {
            switch (code) {
                case AccessAcceptMsg.PACKET_CODE:
                    msg = new AccessAcceptMsg(secret, reqMsg);
                    break;
                case AccessChallengeMsg.PACKET_CODE:
                    msg = new AccessChallengeMsg(secret, reqMsg);
                    break;
                case AccessRejectMsg.PACKET_CODE:
                    msg = new AccessRejectMsg(secret, reqMsg);
                    break;
                case AccountingResponseMsg.PACKET_CODE:
                    msg = new AccountingResponseMsg(secret, reqMsg);
                    break;
                default:
                    throw new RadiusCodeErrorException();
            }
            msg.parse(input);
        } catch (RadiusException e) {
            e.printStackTrace();
        }
        return msg;
    }

    public static RespRadiusMsg parseRespPacket(byte[] input, String secret, byte[] reqMsgByte) {
        ReqRadiusMsg reqMsg = parseReqPacket(reqMsgByte, secret);
        return  parseRespPacket(input, secret, reqMsg);
    }

}
